#include "device.h"
#include "finger.h"
#include "osal.h"

/* 调试打印接口 */
#define FINGER_LOG(format, ...) OSAL_LOG(C_GREEN format C_NONE, ##__VA_ARGS__)

#define UART_VHW_FINGER vUART_8
#define IRQ_VHW_FINGER vPIN_I5
#define POWER_VHW_FINGER vPIN_C29

/* 指纹检测事件 */
#define EVENT_FINGER_DETECT (0X00000001) //指纹检测事件
#define EVENT_INIT_FINGER (0X00000002)
#define EVENT_UART_PROTOCOL (0X00000004)
#define EVENT_FINGER_POWEROFF (0X00000008)

/* FINGER组件的NV大小 */
#define FINGER_NV_SIZE (10) //目前实际只用到2 Byte
/* NV FINGER组件初始化标识*/
#define FINGER_NV_INIT_FLAG 0xFA

/*==============================================================================================*/

#define FINGER_RB_RXBUF_LENGTH 64

#define PROTOCOL_PACKET_STX 0XEF01
#define PROTOCOL_IC_ADDR 0XFFFFFFFF

typedef void (*Finger_send_cb_fun_t)(uint8_t *ackpacket); //发送回调类型

#pragma pack(1)
/* 协议头结构 */
typedef struct
{
    uint16_t stx;     //数据头
    uint32_t ic_addr; //芯片地址
    uint8_t pack_flg; //包标识
    uint16_t len;     //数据长度
} ProtocolDataHead_stu_t;

/* 命令包结构 */
typedef struct
{
    ProtocolDataHead_stu_t head;
    uint8_t cmd;
    uint8_t dataBuf[]; //数据域长度不定 最后两字节是校验和
} CmdPacket_stu_t;

/* 应答包结构 */
typedef struct
{
    ProtocolDataHead_stu_t head;
    uint8_t confrim_code; //确认码
    uint8_t dataBuf[];    //数据域长度不定 最后两字节是校验和
} AckPacket_stu_t;

// tx命令包结构
typedef struct
{
    uint8_t buffer[MAX_PACKAGE_LEN]; //发送缓存
    uint16_t len;                    //数据长度
    uint32_t acktimeout;             //等待ACK的超时时间（为0：不需要ACK）
    Finger_send_cb_fun_t cb;         //发送命令回调（为NULL：不需要回调）
} uart_txcmd_packet_stu_t;

/* 命令包发送状态信息 */
static struct
{
    uart_txcmd_packet_stu_t data; //数据
    uint8_t cmd;                  //发送的命令
    uint32_t timeStamp;           //最后一次发送的时间戳
    uint8_t cnt;                  //发送次数（可能重发）
    enum
    {                    //当前发送的状态
        TX_STA_IDLE,     //空闲
        TX_STA_WAIT_ACK, //等待模块回复应答包
    } status;
    RingBufferHandle_t tbHandle;
} CmdPacketTxInfo;

/* 命令包接收状态信息：记录蓝牙和Uart两个设备的发送状态 */
static struct
{
    uint8_t protocolBuf[MAX_PACKAGE_LEN]; //协议解析缓存
    uint8_t protocolCount;                //协议解析计数变量
    RingBufferHandle_t rbHandle;
    ExtendKdsMsg_t *rx_msg;
    enum
    {
        RX_STA_IDLE,     //空闲
        RX_STA_SEND_ACK, //正在发送多包ACK
    } status;
} CmdPacketRxInfo;

#pragma pack()

/* 定义发送缓存 */
static uint8_t uart_tx_buffer[MAX_PACKAGE_LEN] = {0};
static uint16_t tx_ctrl_flg = 0;

void (*Finger_send_timeout_cb)(void) = NULL;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 * @brief  打印HEX数据，最多只能打印32字节
 * @note
 *
 * @param  pData：数据指针
 * @param  len：数据长度
 */
static void Finger_PrintfHexData(char *Msg, uint8_t *pData, uint16_t len)
{
    char *str_buffer = OSAL_Malloc(len * 3 + 1);
    if (str_buffer != NULL)
    {
        memset(str_buffer, 0, len * 3 + 1);
        FINGER_LOG("%s:%d(Bytes)\r\n", Msg, len);
        if (str_buffer != NULL)
        {
            for (int i = 0; i < len; i++)
            {
                sprintf(&str_buffer[i * 3], "%02X ", pData[i]);
            }
            FINGER_LOG("%s\r\n\r\n", str_buffer);
        }
    }
    if (str_buffer)
        OSAL_Free(str_buffer);
}

uint16_t Finger_CalcCheckSum(uint8_t *pbuf, uint16_t len)
{
    uint16_t i;
    uint16_t sum = 0;

    for (i = 0; i < len; i++)
    {
        sum += *(pbuf + i);
    }
    return sum;
}

/**
 * @brief  获取发送缓存区的状态
 * @note
 *
 * @return 缓存区为空返回0
 */
static uint8_t Finger_GetTxBufferStatus(void)
{
    return tx_ctrl_flg;
}

/**
 * @brief  处理发送缓存
 * @note   将发送缓存区的数据，通过串口发出，并处理Int控制逻辑
 *
 */
static void Finger_ProcessTxBuffer(void)
{
    uint8_t *pSendBuf = uart_tx_buffer;
    if (tx_ctrl_flg > 0)
    {
        if (tx_ctrl_flg & 0X8000)
        {
            /* 调用硬件层write接口，发出数据 */
            Finger_PrintfHexData("Uart send packet", pSendBuf, tx_ctrl_flg & 0X7FFF);
            Device_Write(UART_VHW_FINGER, pSendBuf, tx_ctrl_flg & 0X7FFF, 0);
            tx_ctrl_flg = 0;
        }
        else
        {
            tx_ctrl_flg |= 0X8000;
        }
    }
}

/**
 * @brief  处理应答包
 * @note
 *
 * @param  pData：数据包地址
 */
void Finger_ProcessRxConfrimPacket(uint8_t *pData)
{
    AckPacket_stu_t *pPackeData = (AckPacket_stu_t *)pData;

    FINGER_LOG("confrim_code:%2X", pPackeData->confrim_code);

    if (CmdPacketTxInfo.status == TX_STA_WAIT_ACK)
    {
        if  (CmdPacketTxInfo.data.cb != NULL)
        {
            CmdPacketTxInfo.data.cb(pData);
            CmdPacketTxInfo.data.cb = NULL;
        }

        CmdPacketTxInfo.status = TX_STA_IDLE;
    }
}

/**
 * @brief  解析接收的数据包
 * @note
 *
 * @param  pData：数据包地址
 */
static void Finger_ParseRxPacket(uint8_t *pData)
{
    ProtocolDataHead_stu_t *pPacketHead = (ProtocolDataHead_stu_t *)pData;

    if (pData == NULL)
    {
        return;
    }

    if (pPacketHead->pack_flg == 0x07)
    {
        /* 处理接收的确认包 */
        Finger_ProcessRxConfrimPacket(pData);
    }
    else if (pPacketHead->pack_flg == 1)
    {
        /* 处理接收的数据包 */
    }
    else
    {
        /* 处理接收数据结束包 */
    }
}

/**
 * @brief  从底层环形缓存获取一包数据并解析
 *
 * @note   底层驱动收到数据，会暂存在环形缓存区
 *
 * @return 返回解析后的数据包地址，解析失败返回NULL
 */
static uint8_t *Finger_GetOnePacket(void)
{
    static uint8_t getPacketTimeoutCnt = 0;
    uint8_t tmpData = 0;
    uint16_t sum;

    if (OSAL_RingBufferRead(CmdPacketRxInfo.rbHandle, &tmpData) == 0)
    {
        /* 连续3次没有读取到数据（30ms） */
        if (++getPacketTimeoutCnt >= 3)
        {
            getPacketTimeoutCnt = 0;
            CmdPacketRxInfo.protocolCount = 0; //清0解析计数
        }
        return NULL;
    }
    getPacketTimeoutCnt = 0;

    uint8_t *pCnt = &(CmdPacketRxInfo.protocolCount);    //解析计数
    uint8_t *protocolBuff = CmdPacketRxInfo.protocolBuf; //解析缓存
    do
    {
        if (*pCnt <= 1)
        {
            if (tmpData == 0xEF)
            {
                protocolBuff[0] = tmpData;
                *pCnt = 1;
            }
            else if (*pCnt == 1 && tmpData == 0x01)
            {
                protocolBuff[1] = tmpData;
                *pCnt = 2;
            }
        }
        else if (*pCnt > 1) //包头通过后才开始解析数据
        {
            protocolBuff[*pCnt] = tmpData;
            *pCnt = *pCnt + 1;
            if (*pCnt > 8)
            {
                CmdPacket_stu_t *pPacketHead = (CmdPacket_stu_t *)protocolBuff;

                uint16_t packetLen;
                packetLen = OSAL_SWAP16(pPacketHead->head.len) + 9;
                if (*pCnt >= MAX_PACKAGE_LEN || packetLen == *pCnt)
                {
                    if (packetLen == *pCnt)
                    {
                        sum = protocolBuff[packetLen - 2] * 256 + protocolBuff[packetLen - 1];
                        if (sum == Finger_CalcCheckSum(&protocolBuff[6], OSAL_SWAP16(pPacketHead->head.len) + 1))
                        {
                            Finger_PrintfHexData("Uart Rx", protocolBuff, packetLen);
                            *pCnt = 0;
                            return protocolBuff; //接收完成
                        }
                        else
                        {
                            Finger_PrintfHexData("Uart Rx CRC ERR", protocolBuff, packetLen);
                        }
                    }
                    *pCnt = 0;
                    return NULL;
                }
            }
        }
    } while (OSAL_RingBufferRead(CmdPacketRxInfo.rbHandle, &tmpData)); // while ( uart_hal_recv_data(&tmpData, 1, uart_dev_active,0) != 0 );
    return NULL;
}

/**
 * @brief  重发命令包，并处理超时逻辑
 *
 * @note   MCU发出命令包后，超时没有收到确认包，就重发
 */
static void Finger_CmdTimeoutProess(void)
{
    uint8_t send_timeout_msg = 0;
    uint32_t currentTime = OSAL_GetTickCount();

    if(CmdPacketTxInfo.data.buffer[9]==0x02 || CmdPacketTxInfo.data.buffer[9]==0x04)
    {
        return;
    }

    if (CmdPacketTxInfo.status == TX_STA_WAIT_ACK) //等待应答包
    {
        if (OSAL_PastTime(currentTime, CmdPacketTxInfo.timeStamp) > CmdPacketTxInfo.data.acktimeout) // ERR:等待应答包超时
        {

            FINGER_LOG("wait ack timeout [0x%x]\r\n",CmdPacketTxInfo.data.buffer[9]);
            send_timeout_msg = 1;
            CmdPacketTxInfo.status = TX_STA_IDLE;
        }
    }

    /* exec timeout callback */
    if (send_timeout_msg)
    {
        if  (Finger_send_timeout_cb != NULL)
        {
            Finger_send_timeout_cb();
        }
        FINGER_LOG("\r\n send msg timeout ... \r\n");
    }
}

/**
 * @brief  Uart任务 通信协议处理
 *
 * @note   该函数会每间隔10ms执行一次
 */
static void Finger_ProtocolPro(void)
{
    if (Finger_GetTxBufferStatus() != 0)
    {
        Finger_ProcessTxBuffer(); //处理发送缓存中的数据
    }
    else
    {
        Finger_ParseRxPacket(Finger_GetOnePacket()); //解析数据
        Finger_CmdTimeoutProess();                   //重发命令包
    }
}

/**
 * @brief  加载待发送的数据
 * @note   将要发出的数据，填入发送缓存区
 *
 * @param  pData：数据指针
 * @param  len：数据长度
 * @return 成功返回SUCCESS，失败返回ERROR
 */
static ErrorStatus Finger_LoadingDataToBeSent(uint8_t *pData, uint16_t len)
{
    uint8_t *pSendBuf = uart_tx_buffer;
    FINGER_LOG("uart_tx_cmd:%02X\r\n", pData[9]);
    if (tx_ctrl_flg == 0)
    {
        tx_ctrl_flg = len;
        memcpy(pSendBuf, pData, len);
        return SUCCESS;
    }
    FINGER_LOG("Loading Tx data failed\r\n");
    return ERROR;
}

/**
 * @brief  判断协议层是否为空闲状态
 * @note
 *
 * @return 空闲：返回SUCCESS， 正忙：返回ERROR
 */
static ErrorStatus Finger_IsProtocolIdle(void)
{
    /* 当前没有发出命令、发送缓存为空、接收的命令也处理完成了，才能发出新命令 */
    if (CmdPacketTxInfo.status == TX_STA_IDLE && Finger_GetTxBufferStatus() == 0 && CmdPacketRxInfo.status == RX_STA_IDLE)
    {
        return SUCCESS;
    }
    return ERROR;
}

//处理TX队列
static void Finger_ProcessTxQueue(void)
{
    uart_txcmd_packet_stu_t txcmd_packet = {0};

    if (Finger_IsProtocolIdle() != SUCCESS)
    {
        return;
    }
    if (OSAL_RingBufferRead(CmdPacketTxInfo.tbHandle, &txcmd_packet) != SUCCESS)
    {
        return;
    }
    CmdPacketTxInfo.data = txcmd_packet;
    CmdPacketTxInfo.timeStamp = OSAL_GetTickCount();
    CmdPacketTxInfo.cnt = 1;
    CmdPacketTxInfo.status = TX_STA_WAIT_ACK;
    Finger_LoadingDataToBeSent(CmdPacketTxInfo.data.buffer, CmdPacketTxInfo.data.len);
}

/**
 * @brief  串口接收回调
 *
 * @return
 */
static void Finger_Receivecb(VirtualHardware_enum_t dev, void *data, uint32_t len)
{
    /* 收到的数据写入缓存 */
    uint8_t i;
    for (i = 0; i < len; i++)
    {
        OSAL_RingBufferWrite(CmdPacketRxInfo.rbHandle, (uint8_t *)(data + i));
    }
}

/************************************************************************************
 ************************************************************************************
 ************************************************************************************
 ************************************************************************************
 ************************************************************************************/

/************sensor cmd*******************************/
#define PS_GENCHAR 0X02    //生成特征  启动单次注册enroll
#define PS_SEARCH 0X04     //搜索指纹
#define PS_REG_MODEL 0X05  //录入结束  生成模板
#define PS_DELETCHAR 0X0C  //删除单个指纹
#define PS_EMPTY 0X0D      //删除全部指纹
#define PS_CANCLE 0X30     //取消指令
#define PS_HAND_SHAKE 0X35 //握手指令
#define PS_LED_OFF 0X40
#define PS_LED_ON 0X41
#define PS_LED_FLASH 0X42
#define PS_IMAGEBK 0XB1
#define PS_GET_VERSION 0XB0

typedef struct
{
    uint8_t cmd;
    Finger_send_cb_fun_t callback;
}  AckPakcet_ProecssFun_t;

//指纹运行状态数据
typedef struct
{
    Finger_WorkMode_enum_t mode; //工作模式
    uint8_t enroll_num;    //注册次数

} Finger_Status_Data_stu_t;


Finger_Status_Data_stu_t finger_status_data;

/* 指纹启动标志 */
static uint8_t start_flag = 0;
/* 指纹初始化标志 */
static uint8_t init_flag = 0;
/* 指纹存储编号 */
static uint8_t temp_save_num = 0;

/* 超时时间内检测手指是否存在 */
static uint16_t finger_time_out = 200; //时间为200ms

__NVRAM static uint8_t finger_wake_flag = 0;


void Finger_PsGenchar_cb(uint8_t *ackpacket);
void Finger_search_cb(uint8_t *ackpacket);
void Finger_PsHandShake_cb(uint8_t *ackpacket);
void Finger_PsCancle_cb(uint8_t *ackpacket);
void Finger_RegModel_cb(uint8_t *ackpacket);
void Finger_DeleteModel_cb(uint8_t *ackpacket);
void Finger_imagebk_cb(uint8_t *ackpacket);
void Finger_GetVersion_cb(uint8_t *ackpacket);
void Finger_wait_acktimeout(void);

AckPakcet_ProecssFun_t Ack_HandleFun[] =
    {
        {PS_LED_ON, NULL},
        {PS_SEARCH, Finger_search_cb},
        {PS_GENCHAR, Finger_PsGenchar_cb},
        {PS_REG_MODEL, Finger_RegModel_cb},
        {PS_DELETCHAR, Finger_DeleteModel_cb},
        {PS_EMPTY, Finger_DeleteModel_cb},
        {PS_HAND_SHAKE, Finger_PsHandShake_cb},
        {PS_CANCLE, Finger_PsCancle_cb},
        {PS_IMAGEBK,Finger_imagebk_cb},
        {PS_GET_VERSION,Finger_GetVersion_cb},
};

#define ACK_HANDLER_LENGH (sizeof(Ack_HandleFun) / sizeof(AckPakcet_ProecssFun_t))

/**
 * @brief  Uart任务 协议层初始化
 *
 * @note
 */
static void Finger_ProtocolInit(void)
{
    CmdPacketTxInfo.status = TX_STA_IDLE;
    CmdPacketTxInfo.cnt = 0;
    CmdPacketRxInfo.status = RX_STA_IDLE;
    CmdPacketRxInfo.rx_msg = NULL;
    memset(CmdPacketRxInfo.protocolBuf, 0, sizeof(CmdPacketRxInfo.protocolBuf));
    CmdPacketRxInfo.protocolCount = 0;
    Finger_send_timeout_cb = Finger_wait_acktimeout;
}

void Finger_send_cmd_pack(uint8_t cmd, uint8_t *pbuf, uint16_t len)
{
    uint8_t buf[50];
    uint16_t i;
    uint16_t sum;
    buf[0] = (PROTOCOL_PACKET_STX >> 8) & 0XFF;
    buf[1] = (PROTOCOL_PACKET_STX)&0XFF;
    buf[2] = (PROTOCOL_IC_ADDR >> 24) & 0XFF;
    buf[3] = (PROTOCOL_IC_ADDR >> 16) & 0XFF;
    buf[4] = (PROTOCOL_IC_ADDR >> 8) & 0XFF;
    buf[5] = (PROTOCOL_IC_ADDR)&0XFF;

    buf[6] = 0x01;

    buf[7] = (len + 3) / 256;
    buf[8] = (len + 3) % 256;

    buf[9] = cmd;

    if  (pbuf != NULL)
    {
        memcpy(&buf[10],  pbuf,  len);
    }

    sum = Finger_CalcCheckSum(&buf[6], len + 4);
    buf[10 + len] = sum / 256;
    buf[11 + len] = sum % 256;

    uart_txcmd_packet_stu_t *send_packer = NULL;
    send_packer = (uart_txcmd_packet_stu_t *)OSAL_Malloc(sizeof(uart_txcmd_packet_stu_t));

    memcpy(send_packer->buffer, buf, len + 12);
    send_packer->len = len + 12;

    if  (cmd == PS_SEARCH || cmd == PS_GENCHAR)
    {
        send_packer->acktimeout = 20000;
    }
    else if(cmd == PS_IMAGEBK)
    {
        send_packer->acktimeout = 3000;
    }
    else
    {
        send_packer->acktimeout = 1500; 
    }

    send_packer->cb = NULL;
    for (i = 0; i < ACK_HANDLER_LENGH; i++)
    {
        if  (Ack_HandleFun[i].cmd == cmd)
        {
            send_packer->cb = Ack_HandleFun[i].callback;
            break;
        }
    }

    if (CmdPacketTxInfo.tbHandle != NULL)
    {
        OSAL_RingBufferWrite(CmdPacketTxInfo.tbHandle, send_packer);
    }
}

/**
 * @brief  发送取消指令
 * @note
 * @return
 */
void Finger_Cancle(void)
{
    CmdPacketTxInfo.status = TX_STA_IDLE;
    Finger_send_cmd_pack(PS_CANCLE, NULL, 0);
}

/**
 * @brief  启动单次注册enroll
 * @note
 * @return
 */
void Finger_onec_enroll(void)
{
    uint8_t data_buf[2];
    data_buf[0] = temp_save_num;
    data_buf[1] = finger_status_data.enroll_num;
    Finger_send_cmd_pack(PS_GENCHAR, data_buf, 2);
}

/**
 * @brief  搜索指纹
 * @note
 * @return
 */
void Finger_search(void)
{
    uint8_t data_buf[5];
    data_buf[0] = 1;
    data_buf[1] = 0;
    data_buf[2] = 0;
    data_buf[3] = 0;
    data_buf[4] = 0;
    Finger_send_cmd_pack(PS_SEARCH, data_buf, 5);
}

/**
 * @brief  删除指纹
 * @note
 * @return
 */
void Finger_DeleteChar(uint8_t startNum, uint8_t Num)
{
    uint8_t data_buf[4];
    data_buf[0] = startNum / 256;
    data_buf[1] = startNum % 256;
    data_buf[2] = Num / 256;
    data_buf[3] = Num % 256;
    Finger_send_cmd_pack(PS_DELETCHAR, data_buf, 4);
}

/**
 * @brief 注册模板回调
 * @note
 * @return
 */
void Finger_RegModel_cb(uint8_t *ackpacket)
{
    AckPacket_stu_t *pPackeData = (AckPacket_stu_t  *)ackpacket;
    FingerMsg_t fingerMsg;
    finger_status_data.enroll_num = 1;
    if (pPackeData->confrim_code == 0) //无错误
    {
        FINGER_LOG("add finger ok ...");
        fingerMsg.action = FINGER_ACTION_ADD_OK;
        fingerMsg.fingerNumber = temp_save_num;
        OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
    }
    else
    {
        fingerMsg.action = FINGER_ACTION_ADD_ERR;
        fingerMsg.fingerNumber = temp_save_num;
        OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
        FINGER_LOG("RegModel error code:%2X",  pPackeData->confrim_code);
    }
}

/**
 * @brief  删除指纹回调
 * @note
 * @return
 */
void Finger_DeleteModel_cb(uint8_t *ackpacket)
{
}

/**
 * @brief  单次enroll指纹回调
 * @note
 * @return
 */
void Finger_PsGenchar_cb(uint8_t *ackpacket)
{
    AckPacket_stu_t *pPackeData = (AckPacket_stu_t  *)ackpacket;
    FingerMsg_t fingerMsg;
    static uint8_t enroll_error_num = 0;

    fingerMsg.action = FINGER_ACTION_GET_IMAGE_OK;
    fingerMsg.fingerNumber = 0xff;
    OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));

    if (pPackeData->confrim_code == 0) //无错误
    {
        if (finger_status_data.enroll_num <= 5)
        {
            finger_status_data.enroll_num++;

            Finger_Processor(800);

            fingerMsg.action = FINGER_ACTION_ENTER_AGAIN;
            fingerMsg.fingerNumber = temp_save_num;
            OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
        }
        else
        {
            enroll_error_num = 0;
            FINGER_LOG("reg model ...");
            Finger_send_cmd_pack(PS_REG_MODEL,  NULL,  0); //录入结束 生成模板
        }
    }
    else  //其他一类错误
    {
        FINGER_LOG("PsGenchar error code:%2X",  pPackeData->confrim_code);
        if  (pPackeData->confrim_code == 0x1f) //表示模板缓冲满（Template buffer full) //表示模板缓冲满（Template buffer full)
        {
            enroll_error_num = 0;
            FINGER_LOG("Template buffer full  reg model ...");
            Finger_send_cmd_pack(PS_REG_MODEL, NULL, 0); //录入结束 生成模板
        }
        else if (pPackeData->confrim_code == 0x25) //用户 ID 已存在
        {
            Finger_DeleteChar(temp_save_num, 1);
            Finger_Processor(800);
            fingerMsg.action = FINGER_ACTION_ENTER_AGAIN;
            fingerMsg.fingerNumber = temp_save_num;
            OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
        }
        else
        {
            enroll_error_num++;
            if (enroll_error_num > 8)
            {
                enroll_error_num = 0;
                FINGER_LOG("enroll_error_num>8 reg model ...");
                Finger_send_cmd_pack(PS_REG_MODEL, NULL, 0); //录入结束 生成模板
            }
            else
            {
                Finger_Processor(800);
                fingerMsg.action = FINGER_ACTION_ENTER_AGAIN;
                fingerMsg.fingerNumber = temp_save_num;
                OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));
            }
        }
    }
}

/**
 * @brief  搜索指纹回调
 * @note
 * @return
 */
void Finger_search_cb(uint8_t *ackpacket)
{
    AckPacket_stu_t *pPackeData = (AckPacket_stu_t  *)ackpacket;
    FingerMsg_t fingerMsg;
    uint16_t num;

    fingerMsg.action = FINGER_ACTION_GET_IMAGE_OK;
    fingerMsg.fingerNumber = 0xff;
    OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));

    if (pPackeData->confrim_code == 0)
    {
        //搜索到指纹
        num = pPackeData->dataBuf[1];
        fingerMsg.action = FINGER_ACTION_VERIFY_OK;
        fingerMsg.fingerNumber = (uint8_t)num;
        FINGER_LOG("FINGER_ACTION_VERIFY_OK num=%d \r\n", fingerMsg.fingerNumber);
        OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));

        OSAL_EventSingleCreate(COMP_FINGER, EVENT_FINGER_POWEROFF, 1500, EVT_PRIORITY_MEDIUM);
    }
    else
    {
        FINGER_LOG("FINGER_ACTION_VERIFY_ERR\r\n");
        fingerMsg.action = FINGER_ACTION_VERIFY_ERR;
        fingerMsg.fingerNumber = 0xff;
        OSAL_MessagePublish(&fingerMsg, sizeof(fingerMsg));

        FINGER_LOG("PsGenchar error code:%2X",  pPackeData->confrim_code);
        Finger_Processor(800);
    }
}

/**
 * @brief  模块握手 回调
 * @note
 * @return
 */
void Finger_PsHandShake_cb(uint8_t *ackpacket)
{
    AckPacket_stu_t *pPackeData = (AckPacket_stu_t *)ackpacket;
    if (pPackeData->confrim_code == 0)
    {
        FINGER_LOG("Hand Shank ok...");
        Finger_send_cmd_pack(PS_LED_ON, NULL, 0);
        Finger_send_cmd_pack(PS_GET_VERSION, NULL, 0);
        if (finger_wake_flag == 1)
        {
            finger_wake_flag = 0;
            Finger_search();
        } 
        else 
        {
            if (start_flag == 0)
            {
                 Finger_send_cmd_pack(PS_IMAGEBK, NULL, 0);
            }  
        }
        start_flag = 1;
    }
    else
    {
        start_flag = 0;
        Finger_Cancle();
        FINGER_LOG("PsHandShaker error code:%2X", pPackeData->confrim_code);
    }
}

/**
 * @brief  取消指令 回调
 * @note
 * @return
 */
void Finger_PsCancle_cb(uint8_t *ackpacket)
{
    AckPacket_stu_t *pPackeData = (AckPacket_stu_t *)ackpacket;
    if (pPackeData->confrim_code == 0)
    {
        if (start_flag == 0)
        {
            Finger_send_cmd_pack(PS_HAND_SHAKE, NULL, 0);
        }
    }
}

/**
 * @brief  更新背景指令 回调
 * @note
 * @return
 */
void Finger_imagebk_cb(uint8_t *ackpacket)
{
    AckPacket_stu_t *pPackeData = (AckPacket_stu_t *)ackpacket;
    if (pPackeData->confrim_code == 0)
    {
        Finger_Processor(0);
    }
}

/**
 * @brief  获取版本号指令 回调
 * @note
 * @return
 */
void Finger_GetVersion_cb(uint8_t *ackpacket)
{
    AckPacket_stu_t *pPackeData = (AckPacket_stu_t *)ackpacket;
    FINGER_LOG("version:%s \r\n",&pPackeData->confrim_code);
}

void Finger_wait_acktimeout(void)
{
    Finger_Cancle();
}

/**
 * @brief  指纹中断处理
 * @note
 * @return
 */
static void Finger_Sensor_Int_Irq_Handler(char *name, uint8_t status, uint8_t times)
{
    // if (status == INPUT_PORT_STA_PRESS && times != 0xFF)
    // {
    //     /* 创建ISR事件 */
        
    // }
    OSAL_EventCreateFromISR(COMP_FINGER);
}

void  Finger_Processor(uint16_t time_ms)
{
    FINGER_LOG("Finger_Processor...");
    if(time_ms == 0)
    {
        if (finger_status_data.mode == FINGER_WORK_MODE_VERIFY)
        {
            Finger_search();
        }
        else if  (finger_status_data.mode == FINGER_WORK_MODE_ADD)
        {
            Finger_onec_enroll();
        }
    }
    else
    {
       OSAL_EventSingleCreate(COMP_FINGER, EVENT_FINGER_DETECT, time_ms, EVT_PRIORITY_MEDIUM); 
    }
   
}





/**
 * @brief  指纹组件中断事件处理
 * @note
 */
static void Finger_Isr_Event_Handle(void)
{
    FINGER_LOG("ISR  finger_status_data.mode: %d %d\r\n", finger_status_data.mode,start_flag);
    OSAL_UpdateSleepTime(AUTO_SLEEP_TIME, 1);
    if  (finger_status_data.mode != FINGER_WORK_MODE_DISABLE && start_flag == 0)
    {
        finger_wake_flag = 1;
        Device_Write(POWER_VHW_FINGER, NULL, 0, 1);
        Finger_send_cmd_pack(PS_HAND_SHAKE,  NULL,  0);
        //Finger_Processor(500);
    }
    else
    {
    }
}

/**
 * @brief  指纹组件初始化
 * @note
 * @return
 */
static void Finger_Init()
{
    if (init_flag == 0)
    {
        Device_RegisteredCB(IRQ_VHW_FINGER, Finger_Sensor_Int_Irq_Handler);
        Device_ConfigCB(IRQ_VHW_FINGER, ENABLE);
    }

    if  (start_flag == 0)
    {
        Finger_send_cmd_pack(PS_HAND_SHAKE,  NULL,  0);
    }
}


static void Finger_ProcessMbox(uint8_t *msg)
{
    switch (msg[0])
    {
    case FINGER_SETWORKMODE: //切换指纹任务工作模式
    {
        uint8_t mode;

        mode = msg[1];
        temp_save_num = msg[2]; //

        if (mode != finger_status_data.mode)
        {
            Finger_Cancle();
            finger_status_data.mode = (WorkMode_enum_t)mode;
            if (finger_status_data.mode == FINGER_WORK_MODE_ADD)
            {
                Finger_Processor(0);
                FINGER_LOG("switch add mode\r\n");
            }
            else if (finger_status_data.mode == FINGER_WORK_MODE_VERIFY)
            {
                Finger_Processor(0);
                FINGER_LOG("switch verify mode\r\n");
            }
            else if (finger_status_data.mode == FINGER_WORK_MODE_DISABLE)
            {
                FINGER_LOG("switch disable mode\r\n");
            }
            finger_status_data.enroll_num = 1; //注册次数清零
        }
        FINGER_LOG("finger work mode :%d, fpc_num :%d\r\n", mode, temp_save_num);
    }
    break;
    case FINGER_DELETEIMAGE: //删除指纹图像
    {
        uint8_t startNum, endNum;
        startNum = msg[1];
        endNum = msg[2];
        FINGER_LOG("Users_DeleteFingerImage: startNum = 0x%02x, endNum = 0x%02x\r\n", startNum, endNum);
        if (startNum == 0XFF && endNum == 0XFF)
        {
            Finger_send_cmd_pack(PS_EMPTY, NULL, 0);
        }
        else
        {
            if (endNum != 1)
            {
                Finger_send_cmd_pack(PS_EMPTY, NULL, 0);
            }
            else
            {
                Finger_DeleteChar(startNum, endNum);
            }
        }
    }
    break;
    default:
        break;
    }
}



/**
 * @brief  FINGER任务函数
 *
 * @note   1.任务函数内不能写阻塞代码
 *         2.任务函数每次运行只处理一个事件
 *
 * @param  event：当前任务的所有事件
 *
 * @return 返回未处理的事件
 */
static uint32_t Finger_Task(uint32_t event)
{
    static uint8_t uart_init_flag = 0;
    /* 系统启动事件 */
    if (event & EVENT_SYS_START)
    {
        FINGER_LOG("screen finger Task start\r\n");
        if (uart_init_flag == 0)
        {
            /* 创建RX环形缓存 */
            CmdPacketRxInfo.rbHandle = OSAL_RingBufferCreate(FINGER_RB_RXBUF_LENGTH, 1);
            /* 创建TX环形缓存 */
            CmdPacketTxInfo.tbHandle = OSAL_RingBufferCreate(5, sizeof(uart_txcmd_packet_stu_t));
            /* 注册串口接收回调 */
            Device_RegisteredCB(UART_VHW_FINGER, Finger_Receivecb);
            /* 初始化UART协议层 */
            Finger_ProtocolInit();
            uart_init_flag = 1;
        }
        Device_Enable(UART_VHW_FINGER);
        Device_Write(POWER_VHW_FINGER, NULL, 0, 1);
        OSAL_EventRepeatCreate(COMP_FINGER, EVENT_UART_PROTOCOL, 10, EVT_PRIORITY_MEDIUM);
        Finger_Init();


        return (event ^ EVENT_SYS_START);
    }


    if (event & EVENT_FINGER_DETECT)
    {
        if (finger_status_data.mode == FINGER_WORK_MODE_VERIFY)
        {
            Finger_search();
        }
        else if  (finger_status_data.mode == FINGER_WORK_MODE_ADD)
        {
            Finger_onec_enroll();
        }
        return (event ^ EVENT_FINGER_DETECT);
    }

    /* 系统中断事件 */
    if (event & EVENT_SYS_ISR)
    {
        Finger_Isr_Event_Handle();
        return (event ^ EVENT_SYS_ISR);
    }

    /* 串口处理事件 */
    if (event & EVENT_UART_PROTOCOL)
    {
        Finger_ProtocolPro();
        Finger_ProcessTxQueue();
        return (event ^ EVENT_UART_PROTOCOL);
    }

    if (event & EVENT_SYS_MBOX)
    {
        uint8_t buffer[50] = {0};
        while (OSAL_MboxAccept(buffer))
        {
            Finger_ProcessMbox(buffer);
        }
        return (event ^ EVENT_SYS_MBOX);
    }

    /* 系统休眠事件 */
    if (event & EVENT_SYS_SLEEP)
    {
        CmdPacketTxInfo.status = TX_STA_IDLE;
        start_flag = 0;
        Device_Disable(UART_VHW_FINGER);
        Device_Write(POWER_VHW_FINGER, NULL, 0, 0);
        FINGER_LOG("Finger task sleep\r\n");
        return (event ^ EVENT_SYS_SLEEP);
    }

    /* 模块掉电事件: 验证成功后1.5S掉电, 让其更新模板 */
    if (event & EVENT_FINGER_POWEROFF)
    {
        Device_Write(POWER_VHW_FINGER, NULL, 0, 0);
        start_flag = 0;
        FINGER_LOG("Finger power off\r\n");
        return (event ^ EVENT_FINGER_POWEROFF);
    }    
    return 0;
}
COMPONENT_TASK_EXPORT(COMP_FINGER, Finger_Task, FINGER_NV_SIZE);

/**
 * @brief  指纹唤醒逻辑处理
 * @param
 * @return
 */
static int32_t Finger_WakeHandle(uint32_t dev)
{
    finger_wake_flag = 1;
    Device_Write(POWER_VHW_FINGER, NULL, 0, 1);
    return 1;
}
COMPONENT_WAKEUP_EXPORT(COMP_FINGER, Finger_WakeHandle, IRQ_VHW_FINGER);
